iT邦幫忙

1

[JavaScript]Date.prototype.toISOString()修正時區,因地制宜

  • 分享至 

  • xImage
  •  

本文主要是講怎樣把Date.prototype.toISOString()的結果改成目前的時區
測試環境在Chrome83.0
JavaScript內建的時間是UTC格式顯現
應該大多數人跟我一樣
不習慣看UTC的時間格式
轉成比較好看的ISO時間格式,時區卻不對,每次看還要自己默默+8之類的

console.log(new Date());
//Sun Jun 14 2020 09:28:33 GMT+0800 (台北標準時間)
console.log(new Date().toISOString())
//2020-06-14T01:30:37.710Z

當然 如果只是要給一般使用者看的話
直接用.toLocaleString()就好

console.log(new Date().toLocaleString());
// 2020/6/14 上午9:28:33

不過當如果要把資料存下來的時候
這個格式是回不去的

console.log(new Date(new Date().toLocaleString()));
// Invalid Date

所以最終我們還是得用ISO格式
我一開始的想法,是直接做時區的平移

let tzoffset = (new Date()).getTimezoneOffset() * 60000; 
let localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -1);
console.log(localISOTime);
//2020-06-14T09:44:17.626

但這個解法看似美好
卻有致命缺點
當你重新的資料庫是跨時區的時候...
把這個資料取出

console.log(new Date(localISOTime));
//只要原先儲存時的時區 跟 資料取出時區不同,答案就不一樣了
//可以是Sun Jun 14 2020 09:44:17 GMT+0800 
//也可以是Sun Jun 14 2020 09:44:17 GMT+0600 
//也可以是Sun Jun 14 2020 09:44:17 GMT+0400 

也就是說忽略時區的ISO時間格式,僅限於使用者只在同一個時區
我自己是傾向
直接覆寫Date.prototype.toISOString()

Date.prototype.toISOString = function () {
    let pad =(n)=>(n < 10)?'0' + n:n;
    let hours_offset = this.getTimezoneOffset() / 60;
    let offset_date = this.setHours(this.getHours() - hours_offset);
    let symbol = (hours_offset >= 0) ? "-" : "+";
    let time_zone = symbol+pad(Math.abs(hours_offset))+ ":00";
    
    return this.getUTCFullYear() +
        '-' + pad(this.getUTCMonth() + 1) +
        '-' + pad(this.getUTCDate()) +
        'T' + pad(this.getUTCHours()) +
        ':' + pad(this.getUTCMinutes()) +
        ':' + pad(this.getUTCSeconds()) +
        '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
        time_zone;
};
console.log(new Date().toISOString())
//2020-06-14T09:57:23.102+08:00
console.log(new Date(new Date().toISOString()).toISOString())
//2020-06-14T09:57:23.103+08:00

這樣的完整ISO格式的資料
不管使用者在地球哪一端使用載入資料庫資料
都能轉成本地時間
方便使用者使用
而且還能保持時間的一致性
不會造成應用上的問題


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
superyngo
iT邦新手 5 級 ‧ 2023-05-03 10:29:47

非常實用,感謝!

我要留言

立即登入留言